#pragma once
#define uint unsigned int
#define NULL 0
#include <vector>
namespace NBE
{
	enum AstarNodeType
	{
		EMPTY = 0,
		START,
		END,
		BLOCKER,
		SEMIBLOCKER,
		OPEN,
		CLOSED,
		CURNODE,
		PATH,
		TOTALTYPE
	};


	class AstarNode
	{
	public:
		AstarNode(int type,uint _x,uint _z,uint _idx):nodeType(type),parent(),
			x(_x),z(_z),idx(_idx),G(0),H(0)
		{}
		~AstarNode()
		{}//nothing

		uint idx;
		uint parent;//index of the parent in the node list
		int nodeType;
		int x;
		int z;

		uint G;//to the start node
		uint H;//to the end node
	};

	struct AstarMap
	{
		AstarMap(std::wstring& nm):width(0),height(0),mapName(nm),startNode(0),endNode(0)
		{}
		~AstarMap()
		{
			nodesList.clear();
		}

		AstarNode& getNode(uint x,uint z)
		{
			return nodesList[ width * z + x  ];
		}
		std::wstring mapName;
		std::vector<AstarNode> nodesList;
		uint width;
		uint height;
		uint startNode;
		uint endNode;
	};

	class AstarApp
	{
	public:
		AstarApp()
		{
			memcpy_s(m_mapSymbol,TOTALTYPE,".SE#/OX@P",TOTALTYPE); 
		}
		~AstarApp(); 

		void loadMaps();

		void processing();

		bool doPathFinding(uint current, uint e,AstarMap* pMap,
			std::vector<uint>& open,std::vector<uint>& closed);
		uint getLowestCostNodeInOpenList(std::vector<uint>& open,AstarMap* pMap);
		uint calToEnd(AstarNode& nd,AstarMap* pMap);
		void addNeighorsToOpenList(uint nd_idx,AstarMap* pMap,std::vector<uint>& open);
		void removeNodeInOpenList(uint idx, std::vector<uint>& open);
		void printOutMap(AstarMap* pMap);
		void printMapOnConsole(AstarMap* pMap);
	private:
		uint m_shaderID;
		std::vector<AstarMap*> m_maps;
		char m_mapSymbol[TOTALTYPE];

	};



}